layui.define(['jquery', 'layer', 'laypage'], function (exports) { //提示：模块也可以依赖其它模块，如：layui.define('layer', callback);
    let $ = layui.jquery,
        layer = layui.layer,
        laypage = layui.laypage;
    let clickTimer = null; // 用于延迟判断的计时器
    //外部接口
    let fm = {
            config: {
                'test': 'test',
                'thumb': {'nopic': '', width: 56, height: 56},
                icon_url: 'ico/',
                btn_upload: false,
                btn_create: false
            }
            ,
            cache: {} //数据缓存
            ,
            index: layui.fm ? (layui.fm.index + 10000) : 0
            //设置全局项
            ,
            set: function (options) {
                var that = this;
                that.config = $.extend({}, that.config, options);
                return that;
            }
            //事件监听
            ,
            on: function (events, callback) {
                return layui.onevent.call(this, 'fileManager', events, callback);
            }
            ,
            dirRoot: []
            ,
            v: '1.0.1.2019.12.26'
        }
        //操作当前实例
        , thisFm = function () {
            var that = this,
                options = that.config,
                id = options.id || options.index;

            if (id) {
                thisFm.that[id] = that; //记录当前实例对象
                thisFm.config[id] = options; //记录当前实例配置项
            }
            return {
                config: options,
                reload: function (options) {
                    that.reload.call(that, options);
                }
            }
        }
        //获取当前实例配置项
        , getThisFmConfig = function (id) {
            var config = thisFm.config[id];
            if (!config) hint.error('The ID option was not found in the fm instance');
            return config || null;
        }
        //构造器
        , Class = function (options) {
            var that = this;
            that.config = $.extend({}, that.config, fm.config, options);
            //记录所有实例
            thisFm.that = {}; //记录所有实例对象
            thisFm.config = {}; //记录所有实例配置项
            that.render();
        };
    //渲染
    Class.prototype.render = function () {
        var that = this
            , options = that.config;

        options.elem = $(options.elem);
        options.where = options.where || {};
        options.id = options.id || options.elem.attr('id') || that.index;

        //请求参数的自定义格式
        options.request = $.extend({
            pageName: 'page'
            , limitName: 'limit'
        }, options.request)

        //响应数据的自定义格式
        options.response = $.extend({
            statusName: 'code'
            , statusCode: 0
            , msgName: 'msg'
            , dataName: 'data'
            , countName: 'count'
        }, options.response);

        //如果 page 传入 laypage 对象
        if (typeof options.page === 'object') {
            options.limit = options.page.limit || options.limit;
            options.limits = options.page.limits || options.limits;
            that.page = options.page.curr = options.page.curr || 1;
            delete options.page.elem;
            delete options.page.jump;
        }

        if (!options.elem[0]) return that;
        //渲染主体
        var _html = '<div class="layui-card" style="height:100%">' +
            '<div class="layui-card-body" style="display:flex;flex-direction:column;height:100%">' +
            '<div class="file-body layui-form"  style="height: calc(100% - 120px);overflow: auto;" >' +
            '<ul class="fileManager layui-row fm_body layui-col-space10" id="gridContainer">' +
            '</ul>' +
            '</div>' +
            '<hr><div ><div class="layui_page_' + options.id + '" id="layui_page_' + options.id + '"></div></div></div>';

        options.elem.html(_html);

        options.index = that.index;
        that.key = options.id || options.index;
        //各级容器
        that.layPage = options.elem.find('.layui_page_' + options.id);
        that.layBody = options.elem.find('.fm_body');
        that.layPathBar = options.elem.find('.path_bar');
        that.layToolBar = options.elem.find('.tool_bar');
        that.pullData(that.page); //请求数据
        that.events(); //事件
    }

    //页码
    Class.prototype.page = 1;

    //获得数据
    Class.prototype.pullData = function (curr) {
        var that = this,
            options = that.config,
            request = options.request,
            response = options.response,
            _status = false;

        that.startTime = new Date().getTime(); //渲染开始时间
        if (options.url) { //Ajax请求
            var params = {};
            params[request.pageName] = curr;
            params[request.limitName] = options.limit;

            //参数
            var data = $.extend(params, options.where);
            if (data.pid && data.pid !== '') {
                if (options.contentType && options.contentType.indexOf("application/json") === 0) { //提交 json 格式
                    data = JSON.stringify(data);
                }
                that.loading();
                $.ajax({
                    type: options.method || 'get',
                    url: options.url,
                    contentType: options.contentType,
                    data: data,
                    async: false,
                    dataType: 'json',
                    headers: options.headers || {},
                    success: function (res) {
                        //如果有数据解析的回调，则获得其返回的数据
                        if (typeof options.parseData === 'function') {
                            res = options.parseData(res) || res;
                        }
                        //检查数据格式是否符合规范
                        if (res[response.statusName] !== response.statusCode) {

                            that.errorView(
                                res[response.msgName] ||
                                ('返回的数据不符合规范，正确的成功状态码应为："' + response.statusName + '": ' + response.statusCode)
                            );
                        } else {
                            // console.log(res, curr, res[response.countName]);
                            that.renderData(res, curr, res[response.countName]);

                            options.time = (new Date().getTime() - that.startTime) + ' ms'; //耗时（接口请求+视图渲染）
                        }
                        typeof options.done === 'function' && options.done(res, curr, res[response.countName]);
                        _status = true;
                    },
                    error: function (e, m) {
                        that.errorView('数据接口请求异常：' + m);

                    }
                });
            }

        }
        return _status;
    };
    //数据渲染
    Class.prototype.renderData = function (res, curr, count) {
        var that = this
            , options = that.config
            , data = res[options.response.dataName] || []

        //渲染数据
        var _content = ''
        layui.each(data, function (i, v) {
            let _img, _type = v.type;

            switch (v.type) {
                case 'dir':
                    _img = '<div  style="width:100px;height:100px;line-height:100px"><img src="' + options.icon_url + 'dir.png" style="vertical-align:middle;"></div>';
                    _type = 'DIR';
                    break;
                default:
                    if (v.thumb) {
                        _img = '<div  style="width:100px;height:100px;line-height:100px"><img src="' + __resPath + v.thumb + '"  width="' + options.thumb['width'] + '" height="' + options.thumb['height'] + '"  onerror=\'this.src="' + options.thumb['nopic'] + '"\'  /></div>';
                    } else {
                        if (_type === 'jpg') {
                            _img = '<div  style="width:100px;height:100px;line-height:100px"><img src="' + options.icon_url + 'img.png"  /></div>';
                        } else {
                            if (v.fileExt) {
                                _img = '<div  style="width:100px;height:100px;line-height:100px"><img src="' + options.icon_url + v.fileExt + '.png"  onerror=\'this.src="' + options.thumb['nopic'] + '"\' /></div>';
                            } else {
                                _img = '<div  style="width:100px;height:100px;line-height:100px"><img src="' + options.icon_url + 'dir.png" style="vertical-align:middle;"></div>';
                            }
                        }
                    }
                    break;
            }
            _content += '<li style="display:inline-block" class="grid-item" data-type="' + _type + '" data-index="' + i + '">' +
                '<div class="check-icon"></div><div class="content" align="center">' +
                _img +
                '<p class="layui-elip" title="' + v.name + '">' + v.name + ' </p>' +
                '</div>' +
                '</li>';
        });
        options.elem.find('.fileManager').html(_content);
        const $gridContainer = $('#gridContainer');

        // 为网格项添加事件处理
        $gridContainer.on('mouseenter', '.grid-item', function () {
            const $this = $(this);
            // 如果未选中，显示空心圆形
            if (!$this.hasClass('selected')) {
                $this.find('.check-icon').css({opacity: 1, transform: 'scale(1)'});
            }
        });

        $gridContainer.on('mouseleave', '.grid-item', function () {
            const $this = $(this);
            // 如果未选中，隐藏空心圆形
            if (!$this.hasClass('selected')) {
                $this.find('.check-icon').css({opacity: 0, transform: 'scale(0.9)'});
            }
            // 隐藏高亮背景
            $this.find('.selected-overlay').css('opacity', 0);
        });
        let isDown = options.isDown;
        let clickIcon = null;
        if (options.isDown && isDown !== "0") {
            clickIcon = ".check-icon";
        }
        $gridContainer.on('click', clickIcon, function (e) {
            const $this = $(this).parent();
            // 切换选中状态
            $this.toggleClass('selected');
            var data = fm.cache[that.config.id];
            var index = $this.data('index');
            data = data[index] || {};
            layui.event.call(this,
                'fileManager', 'click(test)'
                , {obj: $this, data: data}
            );
            e.stopPropagation();
        });
        fm.cache[options.id] = data; //记录数据
        //显示隐藏分页栏
        // console.log(that.layPage)
        that.layPage[(count === 0 || (data.length === 0 && curr === 1)) ? 'addClass' : 'removeClass']('layui-hide');
        if (data.length === 0) {
            $("#fileManager").addClass('layui-hide');
            $("#empty_lay").removeClass('layui-hide');
            return;
        } else {
            $("#empty_lay").addClass('layui-hide');
            $("#fileManager").removeClass('layui-hide');
        }
        //同步分页状态
        if (options.page) {
            options.page = $.extend({
                elem: 'layui_page_' + options.id
                , count: count
                , limit: options.limit
                , limits: options.limits || [10, 20, 30, 40, 50, 60, 70, 80, 90]
                , groups: 3
                , layout: ['prev', 'page', 'next', 'skip', 'count', 'limit']
                , prev: '<i class="layui-icon">&#xe603;</i>'
                , next: '<i class="layui-icon">&#xe602;</i>'
                , jump: function (obj, first) {
                    if (!first) {
                        //分页本身并非需要做以下更新，下面参数的同步，主要是因为其它处理统一用到了它们
                        //而并非用的是 options.page 中的参数（以确保分页未开启的情况仍能正常使用）
                        that.page = obj.curr; //更新页码
                        options.limit = obj.limit; //更新每页条数

                        that.pullData(obj.curr);
                    }
                }
            }, options.page);
            options.page.count = count; //更新总条数
            laypage.render(options.page);
        }
    };

    //事件处理
    Class.prototype.events = function () {
        var that = this
            , options = that.config
            , _BODY = $('body')
            , dict = {}
            , filter = options.elem.attr('lay-filter');
        //文件事件
        that.layBody.on('click', 'li', function () { //单击行
            // 获取ul元素
            // 清除之前的计时器
            const $this = $(this);
            const $ul = $this.parents('ul');
            const tid = $this.attr('data-index');
            // 切换选中状态,直接选中
            $this.addClass('selected');
            $this.find('.check-icon').css({opacity: 1, transform: 'scale(1)'});
            // 遍历ul中的所有li，index为索引值
            $ul.find('li.selected').each(function () {
                const $li = $(this);
                const lid = $li.attr('data-index');
                if (tid !== lid) {
                    $li.find('.check-icon').css({opacity: 0});
                    // 隐藏高亮背景
                    $li.find('.selected-overlay').css('opacity', 0);
                    $li.removeClass('selected');
                }
            });
            setPicEvent.call($this, 'click');
        });
        that.layBody.on('dblclick', 'li', function () { //单击行
            setPicEvent.call(this, 'dblclick');
        });

        //创建点击文件事件监听
        var setPicEvent = function (eventType) {
            var othis = $(this);
            var data = fm.cache[options.id];
            var index = othis.data('index');
            data = data[index] || {};
            layui.event.call(this,
                'fileManager', eventType + '(' + filter + ')'
                , {obj: othis, data: data}
            );
        };
    };

    //请求loading
    Class.prototype.loading = function (hide) {
        var that = this
            , options = that.config;
        if (options.loading) {
            if (hide) {
                that.layInit && that.layInit.remove();
                delete that.layInit;
                that.layBox.find(ELEM_INIT).remove();
            } else {
                that.layInit = $(['<div class="layui-table-init">'
                    , '<i class="layui-icon layui-icon-loading layui-anim layui-anim-rotate layui-anim-loop"></i>'
                    , '</div>'].join(''));
                that.layBox.append(that.layInit);
            }
        }
    };
    //异常提示
    Class.prototype.errorView = function (html) {
        var that = this
        layer.msg(html);

    };
    //重载
    Class.prototype.reload = function (options) {
        var that = this;

        options = options || {};
        delete that.haveInit;

        if (options.data && options.data.constructor === Array) delete that.config.data;
        that.config = $.extend(true, {}, that.config, options);

        that.render();
    };
    //重载
    fm.reload = function (id, options) {
        var config = getThisFmConfig(id); //获取当前实例配置项
        if (!config) return;

        var that = thisFm.that[id];
        that.reload(options);

        return thisFm.call(that);
    };
    //核心入口
    fm.render = function (options) {
        var inst = new Class(options);
        return thisFm.call(inst);
    };
    fm.getSelect = function () {
        const id = "fileManager";
        const $ul = $('#gridContainer');
        const select = []
        var data = fm.cache[id];
        $ul.find('li.selected').each(function () {
            const $li = $(this);
            const lid = $li.data('index');
            select.push(data[lid]);
        });
        console.log(select)
        return select[0];
    }
    fm.getSelectIds = function () {
        const id = "fileManager";
        const $ul = $('#gridContainer');
        const select = []
        var data = fm.cache[id];
        $ul.find('li.selected').each(function () {
            const $li = $(this);
            const lid = $li.data('index');
            select.push(data[lid].id);
        });
        return select.join(",");
    }

    fm.getSelectDir = function () {
        const id = "fileManager";
        const $ul = $('#gridContainer');
        const select = []
        var data = fm.cache[id];
        $ul.find('li.selected').each(function () {
            const $li = $(this);
            const lid = $li.data('index');
            const d = data[lid];
            if (d.type === 'dir') {
                select.push(data[lid].id);
            }

        });
        return select;
    }
    fm.getCheckNumber = function () {
        const $ul = $('#gridContainer');
        return $ul.find('li.selected').length;
    }
    exports('fileManager', fm);
});